﻿using System;
using System.Linq;
using GdNet.Core.Domain;
using GdNet.Core.Domain.Metadata;
using NHibernate;
using NHibernate.Type;

namespace GdNet.Integrations.NHibernate.Interceptors
{
    public class EntityWithModificationInterceptor : EmptyInterceptor
    {
        public override bool OnSave(object entity, object id, object[] state, string[] propertyNames, IType[] types)
        {
            return this.UpdateEntity(entity, ref state, ref propertyNames);
        }

        public override bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, IType[] types)
        {
            return this.UpdateEntity(entity, ref currentState, ref propertyNames);
        }

        private bool UpdateEntity(object entity, ref object[] state, ref string[] propertyNames)
        {
            return this.UpdateEntityWithModification(entity, ref state, ref propertyNames);
        }

        protected bool UpdateEntityWithModification(object entity, ref object[] state, ref string[] propertyNames)
        {
            if (entity is IEntityWithModification)
            {
                var createdByPropertyIndex = propertyNames.ToList().IndexOf(EntityWithModificationMeta.CreatedBy);
                if (string.IsNullOrEmpty((string)state[createdByPropertyIndex]))
                {
                    state[createdByPropertyIndex] = this.GetEmailCurrentUser();

                    var createdAtPropertyIndex = propertyNames.ToList().IndexOf(EntityWithModificationMeta.CreatedAt);
                    state[createdAtPropertyIndex] = DateTime.Now;
                }
                else
                {
                    var lastModifiedByPropertyIndex = propertyNames.ToList().IndexOf(EntityWithModificationMeta.LastModifiedBy);
                    state[lastModifiedByPropertyIndex] = this.GetEmailCurrentUser();

                    var lastModifiedAtPropertyIndex = propertyNames.ToList().IndexOf(EntityWithModificationMeta.LastModifiedAt);
                    state[lastModifiedAtPropertyIndex] = DateTime.Now;
                }
            }

            return true;
        }

        /// <summary>
        /// TODO: replace to return correct email of current user
        /// </summary>
        /// <returns></returns>
        protected virtual string GetEmailCurrentUser()
        {
            return "admin@gdnetwebframework.com";
        }
    }
}
